﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Linq.Expressions;
using System.Threading.Tasks;
using Derbster.Domain;

namespace Derbster.Data
{
    /// <summary>
    /// This is an in-memory version of repository. Note, we don't use the singleton pattern here. 
    /// Instead, we count on Unity to control the lifecycle of these objects. By default, we use
    /// a container-controlled lifecycle, so only one instance of a repository is returned per container.
    /// </summary>
    public class DbLeagueRepository : ILeagueRepository, IDisposable

    {
        private readonly DerbsterDbContext _dbContext;

        public DbLeagueRepository()
        {
            _dbContext = new DerbsterDbContext();
        }

        public League Create(string name)
        {
            League newLeague = new League(name);
            _dbContext.Leagues.Add(newLeague);
            _dbContext.SaveChanges();
            
            return newLeague;
        }

        public League Create(string name, string location)
        {
            League newLeague = new League(name, location);
            _dbContext.Leagues.Add(newLeague);
            _dbContext.SaveChanges();

            return newLeague;
        }

        public League FindById(int id)
        {
            return _dbContext.Leagues.SingleOrDefault(m => m.LeagueId == id);
        }

        public League FindByName(string name)
        {
            return _dbContext.Leagues.SingleOrDefault(m => m.Name.ToLower() == name.ToLower());
        }

        public IEnumerable<League> FindByLocation(string location)
        {
            return _dbContext.Leagues.Where(m => !String.IsNullOrWhiteSpace(m.Location) && m.Location.ToLower() == location.ToLower()).AsEnumerable();
        }

        public League Update(League league)
        {
            _dbContext.SaveChanges();
            return league;
        }

        public void Delete(League league)
        {
            _dbContext.Leagues.Remove(league);
            _dbContext.SaveChanges();
        }

        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }

        protected virtual void Dispose(bool disposing)
        {
            if (disposing && _dbContext != null)
                _dbContext.Dispose();
        }

        public IEnumerator<League> GetEnumerator()
        {
            return _dbContext.Leagues.GetEnumerator();
        }

        IEnumerator IEnumerable.GetEnumerator()
        {
            return GetEnumerator();
        }

        public Expression Expression
        {
            get
            {
                return _dbContext.Leagues.Expression;
            }
        }

        public Type ElementType
        {
            get
            {
                return _dbContext.Leagues.ElementType;
            }
        }

        public IQueryProvider Provider
        {
            get
            {
                return _dbContext.Leagues.Provider;
            }
        }
    }
}
